package com.pms.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import jakarta.servlet.http.HttpServletRequest;

import java.util.Date;
import java.util.Map;

@Slf4j
public class JwtUtils {

    private static final String signKey = "linGe";
    private static final Long expire = 43200000L;
    private static final String TOKEN_HEADER = "Authorization";
    private static final String TOKEN_PREFIX = "Bearer ";

    /**
     * 生成JWT令牌
     * @param claims JWT第二部分负载 payload 中存储的内容
     * @return JWT令牌
     */
    public static String generateJwt(Map<String, Object> claims) {
        return Jwts.builder()
                .addClaims(claims)
                .signWith(SignatureAlgorithm.HS256, signKey)
                .setExpiration(new Date(System.currentTimeMillis() + expire))
                .compact();
    }

    /**
     * 解析JWT令牌
     * @param jwt JWT令牌
     * @return JWT第二部分负载 payload 中存储的内容
     */
    public static Claims parseJWT(String jwt) {
        try {
            return Jwts.parser()
                    .setSigningKey(signKey)
                    .parseClaimsJws(jwt)
                    .getBody();
        } catch (ExpiredJwtException e) {
            log.error("Token已过期: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("Token解析失败: {}", e.getMessage());
            throw e;
        }
    }

    /**
     * 从请求头中获取token并解析用户ID
     * @param request HTTP请求
     * @return 用户ID，如果token无效则返回null
     */
    public static Long getCurrentUserId(HttpServletRequest request) {
        String token = getTokenFromRequest(request);
        if (token == null) {
            return null;
        }

        try {
            Claims claims = parseJWT(token);
            return Long.valueOf(claims.get("id").toString());
        } catch (Exception e) {
            log.error("获取用户ID失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 从请求头中获取token并解析用户角色
     * @param request HTTP请求
     * @return 用户角色，如果token无效则返回null
     */
    public static String getCurrentUserRole(HttpServletRequest request) {
        String token = getTokenFromRequest(request);
        if (token == null) {
            return null;
        }

        try {
            Claims claims = parseJWT(token);
            return claims.get("roleType").toString();
        } catch (Exception e) {
            log.error("获取用户角色失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 从请求头中获取token并解析用户名
     * @param request HTTP请求
     * @return 用户名，如果token无效则返回null
     */
    public static String getCurrentUsername(HttpServletRequest request) {
        String token = getTokenFromRequest(request);
        if (token == null) {
            return null;
        }

        try {
            Claims claims = parseJWT(token);
            return claims.get("name").toString();
        } catch (Exception e) {
            log.error("获取用户名失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 验证token是否有效
     * @param token JWT令牌
     * @return 是否有效
     */
    public static boolean validateToken(String token) {
        try {
            Claims claims = parseJWT(token);
            return !claims.getExpiration().before(new Date());
        } catch (Exception e) {
            log.error("Token验证失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 从请求头中提取token
     * @param request HTTP请求
     * @return token字符串，如果没有token则返回null
     */
    private static String getTokenFromRequest(HttpServletRequest request) {
        String token = request.getHeader(TOKEN_HEADER);
        if (token != null && token.startsWith(TOKEN_PREFIX)) {
            return token.substring(TOKEN_PREFIX.length());
        }
        return null;
    }

    /**
     * 获取token过期时间
     * @return 过期时间的毫秒数
     */
    public static Long getExpireTime() {
        return expire;
    }
}